﻿namespace Instrumenter
{
    class DublinCoreMeta
    {
        private string p_Title;
        private string p_Creator;
        private string p_Subject;
        private string p_Publisher;
        private string p_Language;
        private string p_Rights;

        public string Title
        {
            get { return p_Title; }
            set { p_Title = value; }
        }
        public string Creator
        {
            get { return p_Creator; }
            set { p_Creator = value; }
        }
        public string Subject
        {
            get { return p_Subject; }
            set { p_Subject = value; }
        }
        public string Publisher
        {
            get { return p_Publisher; }
            set { p_Publisher = value; }
        }
        public string Language
        {
            get { return p_Language; }
            set { p_Language = value; }
        }
        public string Rights
        {
            get { return p_Rights; }
            set { p_Rights = value; }
        }

        public DublinCoreMeta() { }
        public DublinCoreMeta(System.Xml.XmlNode Node) { }

        public virtual System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("DublinCoreMeta");
            Node.AppendChild(Doc.CreateElement("Title"));
            Node.AppendChild(Doc.CreateElement("Creator"));
            Node.AppendChild(Doc.CreateElement("Subject"));
            Node.AppendChild(Doc.CreateElement("Publisher"));
            Node.AppendChild(Doc.CreateElement("Language"));
            Node.AppendChild(Doc.CreateElement("Rights"));

            Node.ChildNodes[0].InnerText = p_Title;
            Node.ChildNodes[1].InnerText = p_Creator;
            Node.ChildNodes[2].InnerText = p_Subject;
            Node.ChildNodes[3].InnerText = p_Publisher;
            Node.ChildNodes[4].InnerText = p_Language;
            Node.ChildNodes[5].InnerText = p_Rights;
            return Node;
        }
    }

    class DocumentMeta : DublinCoreMeta
    {
        private System.DateTime p_OnAirDate;
        private System.DateTime p_RecordingDate;

        public System.DateTime OnAirDate
        {
            get { return p_OnAirDate; }
            set { p_OnAirDate = value; }
        }
        public System.DateTime RecordingDate
        {
            get { return p_RecordingDate; }
            set { p_RecordingDate = value; }
        }

        public DocumentMeta() : base()
        {
            p_OnAirDate = System.DateTime.Today;
            p_RecordingDate = System.DateTime.Today;
        }
        public DocumentMeta(System.Xml.XmlNode Node) : base(Node)
        {
            p_OnAirDate = System.Convert.ToDateTime(Node.ChildNodes[0].InnerText, System.Globalization.DateTimeFormatInfo.InvariantInfo);
            p_RecordingDate = System.Convert.ToDateTime(Node.ChildNodes[1].InnerText, System.Globalization.DateTimeFormatInfo.InvariantInfo);
        }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("DocumentMeta");
            Node.AppendChild(base.CreateXMLNode(Doc));
            Node.AppendChild(Doc.CreateElement("OnAirDate"));
            Node.AppendChild(Doc.CreateElement("RecordingDate"));

            Node.ChildNodes[1].InnerText = p_OnAirDate.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo);
            Node.ChildNodes[2].InnerText = p_RecordingDate.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo);

            return Node;
        }
    }

    class AudioFile
    {
        private string p_LocalPath;

        public string LocalPath
        {
            get { return p_LocalPath; }
            set { p_LocalPath = value; }
        }

        public AudioFile() { p_LocalPath = string.Empty; }
        public AudioFile(System.Xml.XmlNode Node)
        {
            p_LocalPath = Node.InnerText;
        }

        public System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("AudioFile");
            Node.InnerText = p_LocalPath;
            return Node;
        }
    }

    abstract class Document
    {
        private string p_Name;
        private string p_LocalPath;
        private DocumentMeta p_Meta;
        private AudioFile p_AudioFile;

        public string Name
        {
            get { return p_Name; }
            set { p_Name = value; }
        }
        public string LocalPath
        {
            get { return p_LocalPath; }
            set { p_LocalPath = value; }
        }
        public DocumentMeta Meta { get { return p_Meta; } }
        public AudioFile AudioFile { get { return p_AudioFile; } }

        public Document()
        {
            p_Name = string.Empty;
            p_LocalPath = string.Empty;
            p_Meta = new DocumentMeta();
            p_AudioFile = new AudioFile();
        }
        public Document(System.Xml.XmlNode Node)
        {
            p_Name = Node.ChildNodes[0].InnerText;
            p_LocalPath = Node.ChildNodes[1].InnerText;
            p_Meta = new DocumentMeta(Node.ChildNodes[2]);
            p_AudioFile = new AudioFile(Node.ChildNodes[3]);
        }

        public virtual System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Document");

            Node.AppendChild(Doc.CreateElement("Name"));
            Node.AppendChild(Doc.CreateElement("LocalPath"));
            Node.AppendChild(p_Meta.CreateXMLNode(Doc));
            Node.AppendChild(p_AudioFile.CreateXMLNode(Doc));
            Node.ChildNodes[0].InnerText = p_Name;
            Node.ChildNodes[1].InnerText = p_LocalPath;

            return Node;
        }
    }

    class Speaker
    {
        private string p_Name;

        public string Name
        {
            get { return p_Name; }
            set { p_Name = value; }
        }

        public Speaker() { p_Name = string.Empty; }
        public Speaker(string Name) { p_Name = Name; }
        public Speaker(System.Xml.XmlNode Node) { p_Name = Node.InnerText; }

        public System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Speaker");
            Node.InnerText = p_Name;
            return Node;
        }
    }

    abstract class Segment
    {
        private string p_Name;
        private string p_Description;
        private string p_IconPath;
        private double p_PositionBegin;
        private double p_PositionEnd;
        private System.Collections.Generic.List<Speaker> p_Speakers;
        private System.Collections.Generic.List<Segment> p_Children;

        public string Name
        {
            get { return p_Name; }
            set { p_Name = value; }
        }
        public string Description
        {
            get { return p_Description; }
            set { p_Description = value; }
        }
        public string IconPath
        {
            get { return p_IconPath; }
            set { p_IconPath = value; }
        }
        public double PositionBegin
        {
            get { return p_PositionBegin; }
            set { p_PositionBegin = value; }
        }
        public double PositionEnd
        {
            get { return p_PositionEnd; }
            set { p_PositionEnd = value; }
        }
        public double Length { get { return p_PositionEnd - p_PositionBegin; } }
        public System.Collections.Generic.List<Speaker> Speakers { get { return p_Speakers; } }

        public Segment()
        {
            p_Name = string.Empty;
            p_Description = string.Empty;
            p_IconPath = string.Empty;
            p_PositionBegin = 0;
            p_PositionEnd = 0;
            p_Speakers = new System.Collections.Generic.List<Speaker>();
            p_Children = new System.Collections.Generic.List<Segment>();
        }
        public Segment(System.Xml.XmlNode Node)
        {
            p_Name = Node.ChildNodes[0].InnerText;
            p_Description = Node.ChildNodes[1].InnerText;
            p_IconPath = Node.ChildNodes[2].InnerText;
            p_PositionBegin = System.Convert.ToDouble(Node.ChildNodes[3].InnerText);
            p_PositionEnd = System.Convert.ToDouble(Node.ChildNodes[4].InnerText);
            p_Speakers = new System.Collections.Generic.List<Speaker>();
            foreach (System.Xml.XmlNode Speaker in Node.ChildNodes[6].ChildNodes)
                p_Speakers.Add(new Speaker(Speaker));
            p_Children = new System.Collections.Generic.List<Segment>();
            foreach (System.Xml.XmlNode Child in Node.ChildNodes[7].ChildNodes)
                p_Children.Add(CreateFromXML(Child));
        }

        public void AddChild(Segment Child) { p_Children.Add(Child); }
        public void RemoveChild(Segment Child) { p_Children.Remove(Child); }

        public virtual System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Segment");

            Node.AppendChild(Doc.CreateElement("Name"));
            Node.AppendChild(Doc.CreateElement("Description"));
            Node.AppendChild(Doc.CreateElement("IconPath"));
            Node.AppendChild(Doc.CreateElement("PositionBegin"));
            Node.AppendChild(Doc.CreateElement("PositionEnd"));
            Node.AppendChild(Doc.CreateElement("Length"));
            Node.AppendChild(Doc.CreateElement("Speakers"));
            Node.AppendChild(Doc.CreateElement("Children"));

            Node.ChildNodes[0].InnerText = p_Name;
            Node.ChildNodes[1].InnerText = p_Description;
            Node.ChildNodes[2].InnerText = p_IconPath;
            Node.ChildNodes[3].InnerText = p_PositionBegin.ToString();
            Node.ChildNodes[4].InnerText = p_PositionEnd.ToString();
            Node.ChildNodes[5].InnerText = Length.ToString();
            foreach (Speaker Speaker in p_Speakers)
                Node.ChildNodes[6].AppendChild(Speaker.CreateXMLNode(Doc));
            foreach (Segment Child in p_Children)
                Node.ChildNodes[7].AppendChild(Child.CreateXMLNode(Doc));
            return Node;
        }

        public static Segment CreateFromXML(System.Xml.XmlNode Node)
        {
            if (Node.Attributes["type"].Value == "Introduction")
                return new Introduction(Node);
            else if (Node.Attributes["type"].Value == "Report")
                return new Report(Node);
            else if (Node.Attributes["type"].Value == "Subject")
                return new Subject(Node);
            else if (Node.Attributes["type"].Value == "Interview")
                return new Interview(Node);
            return null;
        }
    }








    abstract class JournalSegment : Segment
    {
        private string p_Title;
        private string p_Content;

        public string Title
        {
            get { return p_Title; }
            set { p_Title = value; }
        }
        public string Content
        {
            get { return p_Content; }
            set { p_Content = value; }
        }

        public JournalSegment() : base()
        {
            p_Title = string.Empty;
            p_Content = string.Empty;
        }
        public JournalSegment(System.Xml.XmlNode Node) : base(Node)
        {
            p_Title = Node.ChildNodes[8].InnerText;
            p_Content = Node.ChildNodes[9].InnerText;
        }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("JournalSegment");
            Node.AppendChild(base.CreateXMLNode(Doc));
            Node.AppendChild(Doc.CreateElement("Title"));
            Node.AppendChild(Doc.CreateElement("Content"));
            Node.ChildNodes[1].InnerText = p_Title;
            Node.ChildNodes[2].InnerText = p_Content;
            return Node;
        }
    }

    class Introduction : JournalSegment
    {
        public Introduction() : base() { }
        public Introduction(System.Xml.XmlNode Node) : base(Node) { }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Introduction");
            Node.AppendChild(base.CreateXMLNode(Doc));
            return Node;
        }
    }

    class Report : JournalSegment
    {
        private System.DateTime p_Date;
        private Speaker p_Reporter;

        public System.DateTime Date
        {
            get { return p_Date; }
            set { p_Date = value; }
        }
        public Speaker Reporter
        {
            get { return p_Reporter; }
        }

        public Report() : base()
        {
            p_Date = System.DateTime.Today;
            p_Reporter = new Speaker();
        }
        public Report(System.Xml.XmlNode Node) : base(Node)
        {
            p_Date = System.Convert.ToDateTime(Node.ChildNodes[10].InnerText, System.Globalization.DateTimeFormatInfo.InvariantInfo);
            p_Reporter = new Speaker(Node.ChildNodes[11]);
        }
        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Report");
            Node.AppendChild(base.CreateXMLNode(Doc));
            Node.AppendChild(Doc.CreateElement("Date"));
            Node.AppendChild(p_Reporter.CreateXMLNode(Doc));
            Node.ChildNodes[1].InnerText = p_Date.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo);
            return Node;
        }
    }

    class Subject : JournalSegment
    {
        public Subject() : base() { }
        public Subject(System.Xml.XmlNode Node) : base(Node) { }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Subject");
            Node.AppendChild(base.CreateXMLNode(Doc));
            return Node;
        }
    }

    class Interview : JournalSegment
    {
        private System.DateTime p_Date;
        private Speaker p_Interviewer;
        private Speaker p_Interviewed;

        public System.DateTime Date
        {
            get { return p_Date; }
            set { p_Date = value; }
        }
        public Speaker Interviewer { get { return p_Interviewer; } }
        public Speaker Interviewed { get { return p_Interviewed; } }

        public Interview() : base()
        {
            p_Date = System.DateTime.Today;
            p_Interviewer = new Speaker();
            p_Interviewed = new Speaker();
        }
        public Interview(System.Xml.XmlNode Node): base(Node)
        {
            p_Date = System.Convert.ToDateTime(Node.ChildNodes[10].InnerText, System.Globalization.DateTimeFormatInfo.InvariantInfo);
            p_Interviewer = new Speaker(Node.ChildNodes[11]);
            p_Interviewed = new Speaker(Node.ChildNodes[12]);
        }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = Doc.CreateElement("Interview");
            Node.AppendChild(base.CreateXMLNode(Doc));
            Node.AppendChild(Doc.CreateElement("Date"));
            Node.AppendChild(p_Interviewer.CreateXMLNode(Doc));
            Node.AppendChild(p_Interviewed.CreateXMLNode(Doc));
            Node.ChildNodes[1].InnerText = p_Date.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo);
            return Node;
        }
    }

    class Journal : Document
    {
        private System.Collections.Generic.List<Speaker> p_Presentators;
        private System.Collections.Generic.List<Segment> p_Segments;

        public System.Collections.Generic.List<Speaker> Presentators { get { return p_Presentators; } }

        public Journal() : base()
        {
            p_Presentators = new System.Collections.Generic.List<Speaker>();
            p_Segments = new System.Collections.Generic.List<Segment>();
        }
        public Journal(System.Xml.XmlNode Node) : base(Node)
        {
            p_Presentators = new System.Collections.Generic.List<Speaker>();
            p_Segments = new System.Collections.Generic.List<Segment>();
            foreach (System.Xml.XmlNode NodeSpeaker in Node.ChildNodes[4].ChildNodes)
                p_Presentators.Add(new Speaker(NodeSpeaker));
            foreach (System.Xml.XmlNode NodeSegment in Node.ChildNodes[5].ChildNodes)
                p_Segments.Add(Segment.CreateFromXML(NodeSegment));
        }

        public void AddChild(Segment Child) { p_Segments.Add(Child); }
        public void RemoveChild(Segment Child) { p_Segments.Remove(Child); }

        public override System.Xml.XmlNode CreateXMLNode(System.Xml.XmlDocument Doc)
        {
            System.Xml.XmlNode Node = base.CreateXMLNode(Doc);

            Node.AppendChild(Doc.CreateElement("Presentators"));
            Node.AppendChild(Doc.CreateElement("Segments"));

            foreach (Speaker Speaker in p_Presentators)
                Node.ChildNodes[4].AppendChild(Speaker.CreateXMLNode(Doc));
            foreach (Segment Segment in p_Segments)
                Node.ChildNodes[5].AppendChild(Segment.CreateXMLNode(Doc));

            return Node;
        }
    }
}